import logging
import random
import time
import json
import math
import inspect
import os
import sys

logger = logging.getLogger(__name__)

CURRENTDIR = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
PARENTDIR = os.path.dirname(CURRENTDIR)
sys.path.insert(0, CURRENTDIR)
sys.path.insert(0, PARENTDIR)

from web.common.fpval import safarifpval, chromefpval, firefoxfpval
from web.common.rval import safarirval, chromerval, firefoxrval
from web.common.informlib import get_siteinform


class CookieGen(object):
    def __init__(self, cookie, url, useragent):
        self.ajtype = 0
        self.ajindx = 0
        self.cookie = cookie
        self.timestamp = time.time_ns() // 1000000
        self.useragent = useragent
        self.url = url
        self.width = str(random.randint(1200, 1920))
        self.height = str(random.randint(768, 1040))
        self.cskey = "0a46G5m17Vrp4o4c"
        self.apikey = "afSbep8yjnZUjq3aL010jO15Sawj2VZfdYK8uY90uxq"
        self.version = "1.43"
        if "Chrome" in self.useragent:
            self.reqinfo = "12147"
            self.fpval = chromefpval()
            self.rcfps = chromerval()
            self.productsub = "20030107"
        elif "Safari" in self.useragent:
            self.fpval = safarifpval()
            self.rcfps = safarirval()
            self.reqinfo = "11011"
            self.productsub = "20030107"
        else:
            self.fpval = firefoxfpval()
            self.rcfps = firefoxrval()
            self.reqinfo = "11059"
            self.productsub = "20100101"
        self.language = "en-US"
        self.engine = "Gecko"
        self.plugins = str(random.randint(1, 4))
        self.headless = "0"
        self.newwindow = "0"
        self.spambot = "0"
        self.availwidth = "1920"
        self.availheight = "1126"
        self.screenwidth = "1920"
        self.screenheight = "1200"
        self.windowwidth = str(self.width)
        self.windowheight = str(self.height)
        self.windowowidth = "1920"
        self.isie = "0"
        self.docmode = "0"
        self.webstore = "0"
        self.online = "1"
        self.opera = "0"
        self.firefox = "0"
        self.safari = "0"
        self.rtcsupport = "1"
        self.windowtop = "0"
        self.vibration = "0"
        self.battery = "0"
        self.foreach = "0"
        self.filereader = "1"
        if "safari" in self.useragent:
            self.motion = "dm_dis"
            self.orientation = "do_dis"
            self.touch = "t_dis"
        else:
            self.motion = "dm_en"
            self.orientation = "do_en"
            self.touch = "t_en"
        self.informinfo = get_siteinform(url)
        self.forminfo = get_siteinform(url)
        self.kact = ""
        self.mact = ""
        self.tact = ""
        self.doact = ""
        self.dmact = ""
        self.pact = ""
        self.vcact = ""
        self.mnr = ""
        self.kevel = 0
        self.mevel = 0
        self.doevel = 0
        self.dmevel = 0
        self.tevel = 0
        self.pevel = 0
        self.kecnt = 0
        self.mecnt = 0
        self.pecnt = 0
        self.tecnt = 0
        self.mmecnt = 0
        self.vccnt = 0
        self.ta = 0
        self.nck = 0
        self.mducecnt = 0
        self.fpvalstr = ""
        self.signature = self._sign(self.cskey, self.apikey)
        date_floor = int(math.floor(int(time.time_ns() // 1000000) / 36e5))
        self.signature += self._sign(str(date_floor), self.signature)
        self.timecalc1 = str(int(self.timestamp / (2016 * 2016)))
        self.timecalc2 = str(int(self.timestamp % 1e7))
        self.timecalc3 = str(int(self.timecalc1) // 23)
        self.timecalc4 = str(int(self.timecalc3) // 6)

    def iterate(self):
        time_elapsed = (
            str(time.time_ns() // 1000000 - self.timestamp) + ","
            if self.ajindx > 0
            else "-999999,"
        )
        time.sleep(0.01)
        if self.ajindx == 0:
            self.fpvalstr = "-1"
        else:
            self.fpvalstr = (
                self.fpval + ";dis;,3;true;true;true;420;true;24;24;true;true;-1"
            )

        sensordata = (
            self.version
            + "-1,2,-94,-100,"
            + self.useragent
            + ",uaend,"
            + self.reqinfo
            + ","
            + self.productsub
            + ","
            + self.language
            + ","
            + self.engine
            + ","
            + self.plugins
            + ","
            + self.headless
            + ","
            + self.newwindow
            + ","
            + self.spambot
            + ","
            + self.timecalc1
            + ","
            + self.timecalc2
            + ","
            + self.availwidth
            + ","
            + self.availheight
            + ","
            + self.screenwidth
            + ","
            + self.screenheight
            + ","
            + self.windowwidth
            + ","
            + self.windowheight
            + ","
            + self.windowowidth
            + ",,cpen:"
            + self.headless
            + ",i1:"
            + self.isie
            + ",dm:"
            + self.docmode
            + ",cwen:"
            + self.webstore
            + ",non:"
            + self.online
            + ",opc:"
            + self.opera
            + ",fc:"
            + self.firefox
            + ",sc:"
            + self.safari
            + ",wrc:"
            + self.rtcsupport
            + ",isc:"
            + self.windowtop
            + ",vib:"
            + self.vibration
            + ",bat:"
            + self.battery
            + ",x11:"
            + self.foreach
            + ",x12:"
            + self.filereader
            + ","
            + str(self._txt_func(self.useragent))
            + ","
            + str(random.random())[0:13]
            + ","
            + str(self.timestamp / 2)
            + ",loc:"
            + "-1,2,-94,-101"
            + ","
            + self.orientation
            + ","
            + self.motion
            + ","
            + self.touch
            + "-1,2,-94,-105,"
            + self.informinfo
            + "-1,2,-94,-102,"
            + self.forminfo
            + "-1,2,-94,-108,"
            + self.kact
            + "-1,2,-94,-110,"
            + self.mact
            + "-1,2,-94,-117,"
            + self.tact
            + "-1,2,-94,-111,"
            + self.doact
            + "-1,2,-94,-109,"
            + self.dmact
            + "-1,2,-94,-114,"
            + self.pact
            + "-1,2,-94,-103,"
            + self.vcact
            + "-1,2,-94,-112,"
            + self.url
            + "-1,2,-94,-115,"
            + str(self.kevel + 1)
            + ","
            + str(self.mevel + 1)
            + ","
            + str(self.tevel)
            + ","
            + str(self.doevel)
            + ","
            + str(self.dmevel)
            + ","
            + str(self.pevel)
            + ","
            + str(self.kevel + self.mevel + self.doevel + self.tevel + self.pevel)
            + ","
            + str(time.time_ns() // 1000000 - self.timestamp)
            + ","
            + str(0)
            + ","
            + str(self.timestamp)
            + ","
            + time_elapsed
            + self.timecalc3
            + ","
            + str(self.kecnt)
            + ","
            + str(self.mecnt)
            + ","
            + self.timecalc4
            + ","
            + str(self.pecnt)
            + ","
            + str(self.tecnt)
            + ","
            + str(time.time_ns() // 1000000 - self.timestamp)
            + ","
            + str(self.ta)
            + ","
            + str(self.nck)
            + ","
            + self.cookie
            + ","
            + str(self._txt_func(self.cookie))
            + ","
            + self.rcfps["rval"]
            + ","
            + self.rcfps["rCFP"]
            + ",26018161"
            + "-1,2,-94,-106,"
            + str(self.ajtype)
            + ","
            + str(self.ajindx)
        )

        sensordata += (
            "-1,2,-94,-119,-1-1,2,-94,-122,0,0,0,0,1,0,0-1,2,-94,-123,"
            + str(self.mnr)
            + "-1,2,-94,-124,"
        )
        text_val = str(self._txt_func(sensordata))

        sensordata += (
            "-1,2,-94,-70,"
            + self.fpvalstr
            + "-1,2,-94,-80,"
            + str(self._txt_func(self.fpvalstr))
            + "-1,2,-94,-116,"
            + str(int(self._time_func(float(self.timecalc2))))
            + "-1,2,-94,-118,"
            + text_val
            + "-1,2,-94,-121,"
        )
        sensordata = (
            self.signature
            + sensordata
            + ";"
            + str(int(time.time_ns() // 1000000 - self.timestamp))
            + ";24;0"
        )

        sensor_string = '{"sensor_data":"' + sensordata + '"}'
        logging.debug(sensor_string)
        if self.ajindx == 0:
            self.ajtype = 9
            self.ajindx = 1
        else:
            self.ajtype = 1
            self.ajindx += 1
        if self.ajindx > 2 and self.motion == "dm_en":
            start_x = random.randint(200, 800)
            start_y = random.randint(200, 1200)
            for _ in range(100):
                self.cma(1, start_x, start_y)
                time.sleep(random.uniform(0.001, 0.005))
                start_x += random.randint(-10, 10)
                start_y += random.randint(-10, 10)
            self.cma(3, start_x, start_y)
            self.lvc(random.choice([2, 3]))

        return sensor_string

    def _sign(self, cs, api):
        temp_string = ""
        cs_length = len(cs)
        api_length = len(api)

        if api_length > 0:
            for index in range(0, cs_length):
                temp_char = cs[index]
                temp_code = ord(temp_char)
                temp_code_2 = ord(api[index % api_length])
                new_code = self._get_code(temp_code, 47, 57, temp_code_2)
                new_char = ""
                if new_code != cs[index]:
                    new_char = chr(new_code)
                    try:
                        temp_string += new_char
                    except:
                        logging.error("Unprintable character => %s" % new_char)

        else:
            logging.error("Signature cannot be blank")
        logging.info("Result signature: %s" % temp_string[0:16])

        return temp_string[0:16]

    def _get_code(self, char_code, const_1, const_2, char_result):
        if const_1 < char_code <= const_2:
            char_code += char_result % (const_2 - const_1)
            if char_code > const_2:
                char_code = char_code - const_2 + const_1

        return char_code

    def _txt_func(self, agent):
        result = -1
        if agent != "":
            try:
                temp_result = 0
                for index in range(0, len(agent)):
                    temp_code = ord(agent[index])
                    if temp_code < 128:
                        temp_result += temp_code
                result = temp_result
            except:
                result = -1

        return str(result)

    def _time_func(self, timestamp):
        temp_val = timestamp
        for index in range(0, 5):
            temp_val2 = int(temp_val / math.pow(10, index)) % 10
            temp_val3 = temp_val2 + 1
            operator = self._get_operator(temp_val3)
            if operator == "+":
                temp_val += temp_val3
            elif operator == "-":
                temp_val -= temp_val3
            elif operator == "*":
                temp_val *= temp_val3
            elif operator == "/":
                temp_val /= temp_val3

        return temp_val

    def _get_operator(self, temp_val):
        temp_result = temp_val % 4
        if temp_result == 2:
            temp_result = 3
        result = temp_result + 42

        return str(result)

    def cma(self, t, x, y):
        try:
            if (t == 1 and self.mmecnt < 100) or (t != 1 and self.mducecnt < 75):
                n = x
                o = y
                i = time.time_ns() // 1000000 - self.timestamp
                c = (
                    str(self.mecnt)
                    + ","
                    + str(t)
                    + ","
                    + str(i)
                    + ","
                    + str(n)
                    + ","
                    + str(o)
                )
                if t != 1:
                    c += ",-1"
                c += ";"
                self.mevel = self.mevel + self.mecnt + t + i + n + 0
                self.mact += c
                self.ta += i
            if t == 1:
                self.mmecnt += 1
            else:
                self.mducecnt += 1
            self.mecnt += 1
        except:
            pass

    def lvc(self, a):
        if self.vccnt < 100:
            t = time.time_ns() // 1000000 - self.timestamp
            e = str(a) + "," + str(t) + ";"
            self.vcact += e
            self.vccnt += 1
